/* 平台公共方法JS */
/**
 * 判断数组中是否包含某值
 * <pre>
 * <code>
 * var ary = ['111','222'];
 * alert(ary.contains('111')) //true
 * </code>
 * </pre>
 * @param {} obj
 * @return {Boolean}
 */
Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
};

/**
 * 删除数组中第i个元素
 * @param index
 */
Array.prototype.removeAt = function (index) {
    this.splice(index, 1);
}
/**
 * 从数组中删除给定元素
 * @param obj
 */
Array.prototype.remove = function (obj) {
    var index = this.indexOf(obj);
    if (index >= 0) {
        this.removeAt(index);
    }
}


var PL = {
    version: '2.0',
    page_size: 10,
    overtime: 60000,
    failureMsg: "系统异常,请重试!",

    /* ====================================================================
     * 页面控件初始化;控件本身仅仅是简单的input输入框,通过此方法可自行在JS中创建组件
     * ====================================================================
     * */
    /**
     * JS端创建一个文本输入域
     * @param {} inputid
     */
    textfield: function (inputid) {
        var self;
        if (typeof inputid == 'string') {
            self = $("#" + inputid);
        } else {
            self = inputid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_text');
        this.uyunsky_text(self);
    },
    //初始化文本框
    uyunsky_text: function (self) {

    },

    /**
     * JS端创建一个数值输入域
     * @param {} inputid
     */
    numberfield: function (inputid, option) {
        var self;
        if (typeof inputid == 'string') {
            self = $("#" + inputid);
        } else {
            self = inputid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_number');
        this.uyunsky_number(self, option);
    },
    //加载数字输入框
    uyunsky_number: function (self, option) {
        var defaults = this._getOptions(self);
        if (PL.isObject(option)) {
            defaults = $.extend(defaults, option);
        }
        self.omNumberField(defaults);
    },

    /**
     * JS端创建一个日期输入域
     * @param {} inputid
     */
    datefield: function (inputid, option) {
        var self;
        if (typeof inputid == 'string') {
            self = $("#" + inputid);
        } else {
            self = inputid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_date');
        this.uyunsky_date(self, option);
    },
    //加载日期输入框
    uyunsky_date: function (self, option) {
        var defaults = this._getOptions(self);
        if (PL.isObject(option)) {
            defaults = $.extend(defaults, option);
        }
        self.omCalendar(defaults);
    },

    /**
     * JS端创建一个下拉列表输入域
     * @param {} inputid
     */
    comboxfield: function (inputid, option) {
        var self;
        if (typeof inputid == 'string') {
            self = $("#" + inputid);
        } else {
            self = inputid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_combox');

        var id = self.attr('combox') + '_combox';
        if ($("#" + id).length == 0) {
            //异步先获取数据置入div数据中
            PL.doService('comboService', {COMBOX: self.attr('combox')},
                {success: function (body) {
                    var list = body.LIST;
                    $("<div>").attr('id', id)
                        .addClass('comboxdata').css('display', 'none')
                        .append(JSON.stringify(list))
                        .insertAfter(self);
                }
                });
        }
        this.uyunsky_combox(self, option);
    },
    //加载下拉列表输入框
    uyunsky_combox: function (self, option) {
        var comboxid = self.attr("combox");
        var datas = $('#' + comboxid + "_combox").text();
        var defaults = {
            dataSource: JSON.parse(datas),
            emptyText: '',//TODO 是否扩展标签库属性
            value: '', // 默认值
            //filterStrategy : 'anywhere',// 输入值与显示值任意位置匹配;默认是first
            filterDelay: 0
        };

        var tabopt = this._getOptions(self);
        defaults = $.extend(defaults, tabopt);//先用标签的属性覆盖
        if (typeof self.attr("listHeight") != 'undefined') {
            defaults.listHeight = parseInt(self.attr("listHeight"));
        }

        if (PL.isObject(option)) {//再用JS中的option覆盖
            defaults = $.extend(defaults, option);
        }
        self.omCombo(defaults);
    },

    /**
     * JS端创建一个下拉列表输入域;input 标签还需要属性listWidth,listHeight
     * @param {} inputid
     */
    combox2field: function (inputid, option) {
        var self;
        if (typeof inputid == 'string') {
            self = $("#" + inputid);
        } else {
            self = inputid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_combox2');
        this.uyunsky_combox2(self, option);
    },
    //加载为自动配置下拉列表
    uyunsky_combox2: function (self, option) {
        self.addClass("om-widget");
        var comboxid = self.attr("combox");
        var conf = {codeName: comboxid};
        if (typeof self.attr("listWidth") != 'undefined') {
            conf.listWidth = parseInt(self.attr("listWidth"));
        }
        if (typeof self.attr("listHeight") != 'undefined') {
            conf.listHeight = parseInt(self.attr("listHeight"));
        }
        conf = $.extend(conf, option);
        self.omCode(conf);
    },

    //TODO 服务名,参数queryParameter
    grid: function (tableid, option) {
        var self;
        if (typeof tableid == 'string') {
            self = $("#" + tableid);
        } else {
            self = tableid;
        }
        self.addClass('uyunsky_base').addClass('uyunsky_grid');
        this.uyunsky_grid(self, option);
    },

    uyunsky_grid: function (self, option) {
        var defaults = {
            dataType: 'json',
            method: 'POST',
            limit: 10,
            title: '查询表格',
            defaultUrl : 'gridQuery.do',
            onSuccess: function (data, testStatus, XMLHttpRequest, event) {
                if (data.total == -1) {
                    if (!PL.isEmpty(option) && PL.isFunction(option.error)) {
                        option.error(data);// 执行失败回调函数
                    } else {
                        // 没有回调函数则弹出返回错误信息
                        if (!PL.isEmpty(data.msg)) {
                            alert(data.msg);
                        }
                    }
                } else {
                    if (!PL.isEmpty(option) && PL.isFunction(option.success)) {
                        // 执行成功回调函数
                        option.success(data);
                    }
                }
            }
        };

        var tabopt = this._getOptions(self);
        defaults = $.extend(defaults, tabopt);//先用标签的属性覆盖
        if (typeof self.attr("title") != 'undefined') {
            defaults.title = self.attr("title");
        }

        if (PL.isObject(option)) {//再用JS中的option覆盖
            defaults = $.extend(defaults, option);
        }
        self.omGrid(defaults);
    },


    /**
     * 初始化文件上传标签
     * @param inputid
     * @param options 与omFileUpload配置相同的对象,
     * 其中增加了一个必输属性和一个成功回调函数
     * {path:'后台保存的子路径'，
     *  success:function(body){
     *      body体内数据为 {
     *         FILENAME:上传文件名
     *         PATH:上传子文件夹
     *      }
     *  }
     * }
     */
    upload: function (inputid, options) {
        var self = $("#" + inputid);
        var actionData = {
            path: PL.isEmpty(options.path) ? '' : options.path
        };
        var defaults = {
            action: baseUrl + 'FileUpload',
            swf: baseUrl + 'js/ui/swf/om-fileupload.swf',
            method: 'GET',
            actionData: actionData,
            multi: false,
            queueSizeLimit: 1,
            onError: function (ID, fileObj, errorObj, event) {
                alert('文件[' + fileObj.name + ']上传失败');
                return;
            },
            onComplete: function (ID, fileObj, response, data, event) {
                if (PL.isFunction(options.success)) {
                    var resbody = eval("(" + response + ")");
                    resbody.FILENAME = fileObj.name;
                    resbody.PATH = options.path;
                    options.success(resbody);
                }
            }
        };
        if (PL.isFunction(options)) {
            defaults = $.extend(defaults, options);
        }
        $('#' + inputid).omFileUpload(defaults);
    },
    /**
     * 文件上传方法,需要先初始化om文件上传标签,然后调用此方法
     * @param {} inputid 文件上传输入框id
     */
    doUpload: function (inputid) {
        $('#' + inputid).omFileUpload('upload');
    },

    // 全局标签库初始化
    _getOptions: function (self) {
        var options = self.attr("options");
        var opt = {};
        if (options !== '') {
            opt = eval("(" + options + ")");
        }
        return opt;
    },
    /*=================控件初始化end====================*/

    /**
     * 文件下载方法,需要后台实现一个文件下载服务
     * @param service 服务id
     * @param data 服务请求数据
     */
    Pdownload : function (service, data) {
        var fromName = 'dform_' + service;
        if ($('#' + fromName).length > 0) {
            $('#' + fromName).remove();
        }
        var $form = $('<form method="post"></form>').css('display', 'none').attr('id', fromName).attr("action", service + ".download");
        $('<input type="hidden" name="data">').val(JSON.stringify(data)).appendTo($form);
        $form.appendTo($(document.body));
        $form.submit();
    },


    /**
     * 获取某个div范围内的所有平台标签值
     * 只支持两层,内部数据再次调用此方法
     * @param {} divId
     * @return {}
     */
    getData: function (divId) {
        var data = {};
        var segids = [];
        $("#" + divId).find(".uyunsky_base").each(function () {
            var self = $(this);
            var cmpid = self.attr("id");
            if (self.hasClass('uyunsky_struct')) {
                data[cmpid] = this._recursion(cmpid, segids);
            } else {
                if (!segids.contains(cmpid)) {
                    data[cmpid] = self.omValue();
                }
            }
        });
        return data;
    },
    /* 目前仅支持一层块 */
    _recursion: function (id, segids) {
        var struct = {};
        $("#" + id).find(".uyunsky_base").each(function () {
            var self = $(this);
            var cmpid = self.attr("id");
            segids.push(cmpid);
            struct[cmpid] = self.omValue();
        });
        return struct;
    },

    /**
     * 将element范围内的所有组件置为只读/或取消只读
     * @param {} elid div id,控制此div内所有元素只读状态
     * @param {} isr : 为true置为只读,为false去掉只读
     */
    readonly: function (elid, isr) {
        if (isr) {//设置只读
            $('#' + elid).find('.uyunsky_base').each(function () {
                $(this).omRonly(true);
            });
        } else {//取消只读
            $('#' + elid).find('.uyunsky_base').each(function () {
                $(this).omRonly(false);
            });
        }
    }
};


PL.isEmpty = function (v) {
    return v === null || v === undefined || v === '';
};

PL.isFunction = function (obj) {
    return $.isFunction(obj);
}

PL.isArray = function (obj) {
    return $.isArray(obj);
}

PL.isObject = function (obj) {
    return $.isPlainObject(obj);
}

PL.inArray = function (value, array) {
    return $.inArray(value, array);
}

PL.trim = function (str) {
    return $.trim(str);
}

/*-------------平台相关----------------*/
/**
 * 平台调用后台服务的function;
 * @param service {} 服务名
 * @param body {} 请求jsons数据
 * @param config {
 *     success : 服务执行成功回调函数
 *     error : 服务执行失败回调函数(通用约定,如果响应头msg不为空,则弹出提示框)
 * } 配置信息项,可以为空
 * @return {json body} 服务成功,返回响应ICSSData的体数据,服务失败返回头数据
 */
PL.doService = function (service, body, config) {
    var data = body;//直接发送请求JSON
    var async = false;
    if (!PL.isEmpty(config) && config.async) {
        async = true;
    }
    $.ajax({
        type: "POST",
        url: service + ".service",
        data: JSON.stringify(data),
        contentType: "application/json;charset=utf-8",
        dataType: "json",
        async: async,
        cache: false,
        timeout: PL.overtime,
        success: function (response) {
            if (response.head.success) {
                // 如果返回body存在,则先回填数据,然后执行自定义回调方法
                if (!PL.isEmpty(response.body)) {
                    var isfill = true;
                    if (!PL.isEmpty(config)) {
                        if (config.notfill) {
                            isfill = false;
                        }
                    }
                    if (isfill) {
                        PL.backfill(response.body);// 回填数据
                    }
                }

                if (!PL.isEmpty(config) && PL.isFunction(config.success)) {
                    // 执行成功回调函数
                    config.success(response.body);
                } else {
                    // 没有回调函数则弹出返回信息
                    if (!PL.isEmpty(response.head.msg)) {
                        alert(response.head.msg);
                    }
                }
            } else {
                if (!PL.isEmpty(config) && PL.isFunction(config.error)) {
                    // 执行失败回调函数
                    config.error(response.head);
                } else {
                    // 没有回调函数则弹出返回错误信息
                    if (!PL.isEmpty(response.head.msg)) {
                        alert(response.head.msg);
                    }
                }
            }
        },
        error: function (msg) {
            alert(PL.failureMsg);
        }
    });
};

/**
 * 根据JSON数据回填页面;根据json数据key值找寻页面相同id,判断页面标签是否input;非input标签回填text值,否则回填value值
 * TODO 测试 radio,checkbox,text,textarea,combobox,datepicker,td,div; grid TODO
 * 层级struct嵌套
 *
 * @param {}
 *          data
 */
PL.backfill = function (data) {
    if (PL.isEmpty(data))
        return;

    //循环json体
    for (var key in data) {
        var data2 = data[key];
        if (PL.isObject(data2)) {
            PL.backfill(data2);
        } else {
            var self = $("#" + key);
            $("#" + key).omValue(data2);
        }
    }
};


/********************************************
 *函数结果：计算乘法运算 ，由于前台a*b 直接计算存在误差；
 ***********************************************/
PL.accMultiply = function (arg1, arg2) {
    var m = 0,
        s1 = arg1.toString(),
        s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length
    } catch (e) {
    }
    try {
        m += s2.split(".")[1].length
    } catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}
/********************************************
 *函数结果：计算加法运算 ，由于前台a+b 直接计算存在误差；
 ***********************************************/
PL.accAdd = function (arg1, arg2) {
    var r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2));
    return ((arg1 * m + arg2 * m) / m).toFixed(Math.max(r1, r2));
}

/********************************************
 *函数结果：计算剑法运算 ，由于前台a-b 直接计算存在误差；
 ***********************************************/
PL.accSubtract = function (arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2));
    //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}


//=====================================================
/*
 *页面初始化后加载标签;JSP标签仅输出了input,需要依靠此JS来加载
 *子页面可单独引入此JS来加载标签
 */
$(function () {
    $(".uyunsky_text").each(function () {
        PL.uyunsky_text($(this));
    });

    $(".uyunsky_number").each(function () {
        PL.uyunsky_number($(this));
    });

    $(".uyunsky_date").each(function () {
        PL.uyunsky_date($(this));
    });

    $(".uyunsky_combox").each(function () {
        PL.uyunsky_combox($(this));
    });

    $(".uyunsky_combox2").each(function () {
        PL.uyunsky_combox2($(this));
    });

    $(".uyunsky_grid").each(function () {
        PL.uyunsky_grid($(this));
    });
});
